package net.mgsx.product.t2m.modisco.impact;
import java.util.ArrayList;
import java.util.Collection;

import net.mgsx.product.t2m.modisco.tools.ModiscoUtils;

import org.eclipse.gmt.modisco.infra.query.core.exception.ModelQueryExecutionException;
import org.eclipse.gmt.modisco.infra.query.core.java.IJavaModelQuery;
import org.eclipse.gmt.modisco.infra.query.core.java.ParameterValueList;
import org.eclipse.gmt.modisco.java.ASTNode;
import org.eclipse.gmt.modisco.java.Assignment;
import org.eclipse.gmt.modisco.java.Expression;
import org.eclipse.gmt.modisco.java.FieldAccess;
import org.eclipse.gmt.modisco.java.MethodInvocation;
import org.eclipse.gmt.modisco.java.TypeAccess;

public class GetWriteAccess implements IJavaModelQuery<ASTNode, Collection<ASTNode>> {
	public Collection<ASTNode> evaluate(final ASTNode context, final ParameterValueList parameterValues)
			throws ModelQueryExecutionException {
		
		Collection<ASTNode> results = new ArrayList<ASTNode>(); 
		evaluateRecursive(context, results, new ArrayList<ASTNode>());
		return results;
	}
	
	private void evaluateRecursive(final ASTNode context, Collection<ASTNode> results, Collection<ASTNode> visitedNodes)
	{
		if(context == null)
		{
			ModiscoUtils.getLogger().logWarning("can't evaluate null node");
		}
		else if(!visitedNodes.contains(context))
		{
			visitedNodes.add(context);
			
			for(Expression expression : ModiscoUtils.getElements(context, Expression.class))
			{
				if(expression instanceof TypeAccess)
				{
					// results.add(expression);
				}
				else if(expression instanceof FieldAccess)
				{
//					for(SingleVariableAccess access : ((FieldAccess) expression).getField().getVariable().getUsageInVariableAccess())
//					{
//						// results.add(access);
//					}
				}
				else if(expression instanceof MethodInvocation)
				{
					evaluateRecursive(((MethodInvocation) expression).getMethod(), results, visitedNodes);
				}
				else if(expression instanceof Assignment)
				{
					Expression left = ((Assignment) expression).getLeftHandSide();
					if(left instanceof FieldAccess)
					{
						results.add(left);
					}
				}
			}
			
		}
		
	}
	
}
